package infiniteindicator.slideview;

import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

import com.bumptech.glide.DrawableRequestBuilder;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.zw.yzk.kabu.R;

import java.io.File;

/**
 * When you want to make your own slider view, you must extends from this class.
 * BaseSliderView provides some useful methods.
 * if you want to show progressbar, you just need to set a progressbar id as @+id/loading_bar.
 * <p/>
 * Thanks to :  https://github.com/daimajia/AndroidImageSlider
 */
public abstract class BaseSliderView {

    public static final String KEY_VIEW_DATA = "BASESLIDERVIEW_VIEW_DATA";

    protected Context mContext;

    private Bundle mBundle;

    /**
     * image will be displayed in targetImageView if some error occurs during.
     */
    private int mImageResForError;

    /**
     * image will be displayed in targetImageView if empty url(null or emtpy String).
     */
    private int mImageResForEmpty;

    private String mUrl;
    private File mFile;
    private int mRes;

    protected OnSliderClickListener mOnSliderClickListener;

    private boolean mIsShowErrorView;

    private BitmapLoadCallBack mBitmapLoadListener;

    public String getImageUrl() {
        return mUrl;
    }
    /**
     * Scale type of the image.
     */
    private ScaleType mScaleType = ScaleType.Fit;

    public enum ScaleType {
        CenterCrop, CenterInside, Fit, FitCenterCrop
    }

    protected BaseSliderView(Context context) {
        mContext = context;
        this.mBundle = new Bundle();
    }

    /**
     * the placeholder image when loading image from url or file.
     *
     * @param resId Image resource id
     * @return
     */
    public BaseSliderView showImageResForEmpty(int resId) {
        mImageResForEmpty = resId;
        return this;
    }

    /**
     * if you set isShowErrorView false, this will set a error placeholder image.
     *
     * @param resId image resource id
     * @return
     */
    public BaseSliderView showImageResForError(int resId) {
        mImageResForError = resId;
        return this;
    }

    public int getImageResForEmpty() {
        return mImageResForEmpty;
    }

    public int getImageResForError() {
        return mImageResForError;
    }

    /**
     * determine whether remove the image which failed to download or load from file
     *
     * @param disappear
     * @return
     */
    public BaseSliderView isShowErrorView(boolean disappear) {
        mIsShowErrorView = disappear;
        return this;
    }

    /**
     * set a url as a image that preparing to load
     *
     * @param url
     * @return
     */
    public BaseSliderView image(String url) {
        if (mFile != null || mRes != 0) {
            throw new IllegalStateException("Call multi image function," +
                    "you only have permission to call it once");
        }
        mUrl = url;
        return this;
    }

    /**
     * set a file as a image that will to load
     *
     * @param file
     * @return
     */
    public BaseSliderView image(File file) {
        if (mUrl != null || mRes != 0) {
            throw new IllegalStateException("Call multi image function," +
                    "you only have permission to call it once");
        }
        mFile = file;
        return this;
    }

    public BaseSliderView image(int res) {
        if (mUrl != null || mFile != null) {
            throw new IllegalStateException("Call multi image function," +
                    "you only have permission to call it once");
        }
        mRes = res;
        return this;
    }

    public String getUrl() {
        return mUrl;
    }

    public boolean isShowErrorView() {
        return mIsShowErrorView;
    }

    public Context getContext() {
        return mContext;
    }

    /**
     * set click listener on a slider image
     *
     * @param l
     * @return
     */
    public BaseSliderView setOnSliderClickListener(OnSliderClickListener l) {
        mOnSliderClickListener = l;
        return this;
    }

    /**
     * When you want to implement your own slider view, please call this method in the end in `getView()` method
     *
     * @param v               the whole view
     * @param targetImageView where to place image
     */
    protected void bindEventAndShow(final View v, ImageView targetImageView) {
        final BaseSliderView me = this;

        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnSliderClickListener != null) {
                    mOnSliderClickListener.onSliderClick(me);
                }
            }
        });

        if (targetImageView == null)
            return;

        mBitmapLoadListener.onLoadStart(me);

        //loadByImageLoader(v, targetImageView);
//        loadByPicasso(v,targetImageView);
        loadByGlide(v, targetImageView);
    }

//    protected void loadByImageLoader(final View v, final ImageView targetImageView) {
//        if(getImageResForEmpty() > 0){
//            targetImageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
//            targetImageView.setImageResource(getImageResForEmpty());
//        }
//
//        final BaseSliderView me = this;
//        SimpleImageLoadingListener listener = new SimpleImageLoadingListener() {
//            @Override
//            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
//                targetImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
//                targetImageView.setImageBitmap(loadedImage);
//
//                if (v.findViewById(R.id.loading_bar) != null) {
//                    v.findViewById(R.id.loading_bar).setVisibility(View.INVISIBLE);
//                }
//                if (mBitmapLoadListener != null) {
//                    mBitmapLoadListener.onLoadComplete(me);
//                }
//            }
//
//            @Override
//            public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
//                if(getImageResForError() > 0){
////                    targetImageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
//                    targetImageView.setImageResource(getImageResForError());
//                }
//                targetImageView.setImageResource(com.photoselector.R.drawable.ic_picture_loadfailed);
//                if (mBitmapLoadListener != null) {
//                    mBitmapLoadListener.onLoadFail(me);
//                }
//            }
//        };
//
//        if (mUrl != null) {
//            ImageLoader.getInstance().loadImage(mUrl, listener);
//        } else if (mFile != null) {
//            ImageLoader.getInstance().loadImage("file://"+mFile.getAbsolutePath(), listener);
//        } else if (mRes != 0) {
//            ImageLoader.getInstance().loadImage("drawable://"+mRes, listener);
//        } else {
//            return;
//        }
//    }

    protected  void loadByGlide(final View v, ImageView targetImageView){
        RequestManager requestManager = Glide.with(mContext);
        DrawableRequestBuilder builder;
        if (mUrl != null) {
            builder =  requestManager.load(mUrl).diskCacheStrategy(DiskCacheStrategy.SOURCE);
        } else if (mFile != null) {
            builder =  requestManager.load(mFile).diskCacheStrategy(DiskCacheStrategy.SOURCE);
        } else if (mRes != 0) {
            builder =  requestManager.load(mRes).diskCacheStrategy(DiskCacheStrategy.SOURCE);
        } else {
            return;
        }

        switch (mScaleType) {
            case Fit:
                builder.fitCenter();
                break;
            case CenterCrop:
                builder.centerCrop();
                break;
            case CenterInside:
                builder.fitCenter();
                break;
        }

        builder.dontAnimate().error(R.drawable.im_default).listener(new RequestListener() {
            @Override
            public boolean onException(Exception e, Object o, Target target, boolean b) {
                if (v.findViewById(R.id.loading_bar) != null) {
                    v.findViewById(R.id.loading_bar).setVisibility(View.INVISIBLE);
                }
                return false;
            }

            @Override
            public boolean onResourceReady(Object o, Object o2, Target target, boolean b,
                                           boolean b1) {
                if (v.findViewById(R.id.loading_bar) != null) {
                    v.findViewById(R.id.loading_bar).setVisibility(View.INVISIBLE);
                }
                return false;
            }
        }).into(targetImageView);
    }

    public BaseSliderView setScaleType(ScaleType type) {
        mScaleType = type;
        return this;
    }

    public ScaleType getScaleType() {
        return mScaleType;
    }

    /**
     * the extended class have to implement getView(), which is called by the adapter,
     * every extended class response to render their own view.
     *
     * @return
     */
    public abstract View getView();

    /**
     * set a listener to get a message , if load error.
     *
     * @param l
     */
    public void setOnImageLoadListener(BitmapLoadCallBack l) {
        mBitmapLoadListener = l;
    }

    public interface OnSliderClickListener {
        public void onSliderClick(BaseSliderView slider);
    }

    /**
     * when you have some extra information, please put it in this bundle.
     *
     * @return
     */
    public Bundle getBundle() {
        return mBundle;
    }

    public interface BitmapLoadCallBack {
        public void onLoadStart(BaseSliderView target);

        public void onLoadComplete(BaseSliderView target);

        public void onLoadFail(BaseSliderView target);
    }
}
